home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Http Server / •OT_Classes / TNetworkAcceptor.cp < prev    next >
Encoding:
Text File  |  1996-01-11  |  9.7 KB  |  333 lines  |  [TEXT/CWIE]

  1. //    TNetworkAcceptor.cp - Macintosh OpenTransport Network Acceptor class object
  2. // 
  3. // Apple Macintosh Developer Technical Support
  4. // Written by:  Vinne Moscaritolo
  5. //
  6. //  Copyright (work in progress)  Apple Computer, Inc All rights reserved.
  7. //
  8. // You may incorporate this sample code into your applications without
  9. // restriction, though the sample code has been provided "AS IS" and the
  10. // responsibility for its operation is 100% yours.  However, what you are
  11. // not permitted to do is to redistribute the source as "DSC Sample Code"
  12. // after having made changes. If you're going to re-distribute the source,
  13. // we require that you make it clear in the source that the code was
  14. // descended from Apple Sample Code, but that you've made changes.
  15. // 
  16.  
  17. #include "TNetworkAcceptor.h"
  18. #include "TThread.h"        
  19.  
  20. // ---------------------------------------------------------------------------
  21. //     NotifyProc (queue up an event)
  22. // ---------------------------------------------------------------------------
  23. //     TNetworkAcceptor OT Notifier Proc  
  24.  
  25. pascal void TNetworkAcceptor::NotifyProc( TNetworkAcceptor* theAcceptor, OTEventCode theEvent, OTResult theResult, void* theParam)
  26. {    
  27.     try
  28.     {
  29. // queue event
  30.         QUEUE_NET_EVENT( theAcceptor, theEvent, theResult, theParam);
  31.     }
  32.  
  33.     catch (TNetworkException &ex)
  34.     {
  35.                 DebugStr("\p TNetworkAcceptor::NotifyProc -- Network Exception.. ");
  36.     }
  37.     
  38.     catch(TMacException &ex)
  39.     {
  40.                 DebugStr("\p TNetworkAcceptor::NotifyProc -- Mac Exception.. ");
  41.     }
  42.     
  43.     catch(...)        // catch everything
  44.     {
  45.                 DebugStr("\p TNetworkAcceptor::NotifyProc -- Other Exception.. ");
  46.     } 
  47.  
  48. }
  49.  
  50.  
  51.  
  52. // ---------------------------------------------------------------------------
  53. //     ~TNetworkAcceptor
  54. // ---------------------------------------------------------------------------
  55. //    Destructor
  56.  
  57. TNetworkAcceptor::~TNetworkAcceptor()
  58. {
  59.     TNetworkSession *aSess;
  60.     
  61.     if(fEndPoint != kOTInvalidEndpointRef)         ::OTCloseProvider(fEndPoint);
  62.     fEndPoint = kOTInvalidEndpointRef;    
  63.     
  64.     if( fLocalAddress) delete fLocalAddress;
  65.  
  66.     while(aSess = (TNetworkSession*) fActiveSessions.RemoveFirst()){
  67.         delete aSess;
  68.         }
  69.  
  70.     while(aSess = (TNetworkSession*) fFreeSessions.RemoveFirst()){
  71.         delete aSess;
  72.         }
  73.  
  74. };
  75.  
  76. // ---------------------------------------------------------------------------
  77. //     TNetworkAcceptor::Open( TNetworkEndpointDescriptor* )
  78. // ---------------------------------------------------------------------------
  79. //    Open Network Acceptor
  80.  
  81. void TNetworkAcceptor::Open(TNetworkEndpointDescriptor* theEPD)
  82. {
  83.  
  84. // create a some thread pool for sessions
  85.     TThread::Allocate( fPrefs.fBuildSessions, kSessionStackSpace);
  86.  
  87. // save configuration info
  88.     fEPD     = theEPD;
  89.     
  90. // Reset Timer
  91.     fStats.fAcceptedSessions = 0;
  92.     fStats.fRejectedSessions = 0;
  93.     fStartTime.Now();
  94.  
  95.  
  96. // Setup a new endpoint
  97.        ThrowIfOTErr( ::OTAsyncOpenEndpoint( theEPD->GetConfiguration() ,0,&fInfo,NotifyProc, this) );
  98.  }
  99.  
  100.  
  101.  
  102. //
  103. // ---------------------------------------------------------------------------
  104. //     TNetworkAcceptor::HandleEvent (TNetworkEvent*)
  105. // ---------------------------------------------------------------------------
  106. //    Network Acceptor Event Handler
  107.  
  108. Boolean TNetworkAcceptor::GetStats (TAcceptorInfo* theStats)
  109. {
  110.  
  111.     if(fPending == kUnBound) return false;
  112.     
  113. // update stats
  114.     fStats.fUpTime                     = fStartTime.Elapsed();    
  115.     fStats.fActiveSessions     = fActiveSessions.Count();
  116.     fStats.fFreeSessions         = fFreeSessions.Count();
  117.         
  118. // return them
  119.     *theStats = fStats;
  120.     return true;
  121. }
  122.  
  123. // ---------------------------------------------------------------------------
  124. //     TNetworkAcceptor::HandleEvent (TNetworkEvent*)
  125. // ---------------------------------------------------------------------------
  126. //    Network Acceptor Event Handler
  127.  
  128. void TNetworkAcceptor::HandleEvent (TNetworkEvent* theEvent)
  129. {
  130.     switch ( theEvent->fEvent ) {
  131.  
  132. ///// OpenEndpoint Completed
  133.             case T_OPENCOMPLETE:                    
  134.                      EventOpenComplete(theEvent);
  135.                     break;
  136. ///// Bind Completed - Listner ready
  137.             case T_BINDCOMPLETE:                                
  138.                     EventBindComplete(theEvent);
  139.                     break;
  140. ///// Client Attemptng Connection
  141.             case T_LISTEN:                                                
  142.                     EventListen(theEvent);
  143.                     break;
  144. ///// Handoff Completed
  145.             case T_ACCEPTCOMPLETE:                            
  146.                     EventAcceptComplete(theEvent);
  147.                     break;
  148. ///// Client Quit 
  149.             case T_DISCONNECT:                            
  150.                     EventDisconnect(theEvent);
  151.                     break;
  152. ///// Rejection Completed
  153.             case T_DISCONNECTCOMPLETE:                
  154.                     EventDisconnectComplete(theEvent);
  155.                     break;
  156. ///// Winding down
  157.             case T_UNBINDCOMPLETE:                            
  158.                     EventUnbindComplete(theEvent);
  159.                     break;
  160. ///// Sesion becomes available        ***** Private Event ******
  161.             case kSessionAvailable:                                        
  162.                     EventSessionAvailable(theEvent);
  163.                     break;
  164. ////..Other ...
  165.             default:                                                                        
  166.                     EventOther(theEvent);
  167.                     break;
  168.         }
  169. }
  170.  
  171.  
  172. // ---------------------------------------------------------------------------
  173. //     TNetworkAcceptor::EventOpenComplete 
  174. // ---------------------------------------------------------------------------
  175. //    Network Endpoint Open Completion Handler
  176.  
  177. void TNetworkAcceptor::EventOpenComplete(TNetworkEvent* theEvent)
  178. {        
  179. //    Save endpoint ref
  180.     fEndPoint =  (EndpointRef) theEvent->fParam;
  181.  
  182. // Initiate Bind
  183.     TAddr* theAddr = fEPD->GetLocalAddress();        // get configured Addreess
  184.     fLocalAddress = theAddr->Clone();                        // create a local Address object
  185.     theAddr->ToNetbuf(&fReqBind.addr);                    // fill in req Netbuf
  186.     fLocalAddress->ToNetbuf(&fRetBind.addr);        // fill in reply Netbuf
  187.     fReqBind.qlen = fPrefs.fMaxOutStanding;            // Number of Outstanding Connections
  188.     
  189.     ThrowIfOTErr( ::OTBind( fEndPoint, &fReqBind, &fRetBind));    
  190.  
  191. }
  192.  
  193. // ---------------------------------------------------------------------------
  194. //     TNetworkAcceptor::EventSessionAvailable
  195. // ---------------------------------------------------------------------------
  196. //    Handle Session becoming avail
  197. void TNetworkAcceptor::EventSessionAvailable(TNetworkEvent* theEvent)
  198. {
  199.     TNetworkSession* theSession = (TNetworkSession*)theEvent->fParam;
  200.     
  201. // If its on the Active List remove it.
  202.     fActiveSessions.Remove(theSession);
  203.     
  204. // If there is a listen pending then use this session
  205.     if(fPending > kNonePending)
  206.         {    
  207.             fPending--;
  208.             DoListen(theSession);
  209.         } else 
  210. // If no listen is pending then save this session on freelist or recycle it
  211.             if( fFreeSessions.Count() <=  fPrefs.fMaxFreeSessions)
  212.                     fFreeSessions.Add(theSession);                    
  213.             else 
  214.                     delete theSession;
  215.  
  216. }
  217.  
  218.  
  219. // ---------------------------------------------------------------------------
  220. //     TNetworkAcceptor::EventBindComplete
  221. // ---------------------------------------------------------------------------
  222. //    Network Endpoint Bind Completion Handler
  223.  
  224. void TNetworkAcceptor::EventBindComplete(TNetworkEvent* theEvent)
  225. {
  226.     TBind *retAddr = (TBind *) theEvent->fParam;
  227.     
  228.     if(!fEPD->ValidateBind(&fReqBind,&fRetBind) )     ThrowMsg("Bind Failed");
  229.     fStartTime.Now();
  230. }
  231.  
  232. // ---------------------------------------------------------------------------
  233. //     TNetworkAcceptor::EventListen()
  234. // ---------------------------------------------------------------------------
  235. //    Client Attemptng Connection
  236.  
  237. void TNetworkAcceptor::EventListen(TNetworkEvent* theEvent)
  238. {
  239.     TNetworkSession *aSess;
  240.     
  241. // If there are free session available, then handle it else create a some spares.
  242.     if( aSess = (TNetworkSession*) fFreeSessions.RemoveFirst())
  243.         DoListen(aSess);
  244.      else {
  245.             for ( int i = 0; i < fPrefs.fBuildSessions; i++) SessionFactory();
  246.              fPending++;
  247.      }
  248. }
  249.  
  250.  
  251. // ---------------------------------------------------------------------------
  252. //     TNetworkAcceptor::EventAcceptComplete
  253. // ---------------------------------------------------------------------------
  254. //    Network Endpoint Handoff Completion Handler
  255.  
  256. void TNetworkAcceptor::EventAcceptComplete(TNetworkEvent* theEvent)
  257. {
  258.     fStats.fAcceptedSessions++;
  259. }
  260.  
  261. // ---------------------------------------------------------------------------
  262. //     TNetworkAcceptor::EventDisconnect
  263. // ---------------------------------------------------------------------------
  264. //    Connecting client quit
  265.  
  266. void TNetworkAcceptor::EventDisconnect(TNetworkEvent* theEvent)
  267. {
  268.     fStats.fDisconSessions++;
  269.    :: OTRcvDisconnect(fEndPoint, nil);
  270. }
  271.  
  272. // ---------------------------------------------------------------------------
  273. //     TNetworkAcceptor::EventDisconnectComplete
  274. // ---------------------------------------------------------------------------
  275. //    Network Endpoint Disconnect Completion Handler
  276.  
  277. void TNetworkAcceptor::EventDisconnectComplete (TNetworkEvent* theEvent)
  278. {
  279.     fStats.fRejectedSessions++;
  280. }
  281.  
  282. // ---------------------------------------------------------------------------
  283. //     TNetworkAcceptor::EventUnbindComplete( )
  284. // ---------------------------------------------------------------------------
  285. //    Network Endpoint Unbind Completion Handler
  286.  
  287. void TNetworkAcceptor::EventUnbindComplete (TNetworkEvent* theEvent)
  288. {
  289.     fPending == kUnBound;
  290. }
  291.  
  292.  
  293. // ---------------------------------------------------------------------------
  294. //     TNetworkAcceptor::EventOther 
  295. // ---------------------------------------------------------------------------
  296. //    Other random event
  297.  
  298. void TNetworkAcceptor::EventOther(TNetworkEvent* theEvent)
  299. {        
  300.         if(theEvent)
  301.             ThrowIfOTErr(noErr);
  302. };
  303.  
  304.  
  305.                         
  306. // ---------------------------------------------------------------------------
  307. //     TNetworkAcceptor::DoListen(aSess)
  308. // ---------------------------------------------------------------------------
  309. void TNetworkAcceptor::DoListen(TNetworkSession *aSess)
  310. {
  311.     TCall *call = aSess->GetCallInfo();
  312.     OSStatus    ErrNo;
  313.     
  314. // Get Connection Information                
  315.     ThrowIfOTErr(::OTListen (fEndPoint, call));                // ***FIX THIS ****
  316.     
  317. // Do you take this client....
  318.         if( fEPD->Filter(call) )
  319. // Accept connection                
  320.             if((ErrNo =  ::OTAccept (fEndPoint, aSess->GetEndpoint(), call)) == kOTNoError ) 
  321.                 {
  322.                 fActiveSessions.Add(aSess);    
  323.                 return;
  324.                 }
  325.                 
  326. // reject connection
  327.     ::OTSndDisconnect (fEndPoint,call);
  328.  
  329. // free up unused session
  330.     fFreeSessions.Add(aSess);    
  331. }
  332.  
  333.